package com.iteaj.iot.boot.core;

import com.iteaj.iot.*;
import com.iteaj.iot.boot.listener.IotFrameworkReadyListener;
import com.iteaj.iot.business.ProtocolHandleFactory;
import com.iteaj.iot.handle.proxy.ProtocolHandleProxyMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.PropertySource;

import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;

/**
 * create time: 2022/1/16
 *
 * @author iteaj
 * @since 1.0
 */
@PropertySource("classpath:IOTCore.properties")
@EnableConfigurationProperties({CoreProperties.class, IotJdbcProperties.class})
@AutoConfigureBefore(TaskSchedulingAutoConfiguration.class)
public class IotCoreConfiguration {

    private final IotCoreProperties coreProperties;

    public IotCoreConfiguration(IotCoreProperties coreProperties) {
        this.coreProperties = coreProperties;
    }

    @Bean
    public IotThreadManager iotThreadManager() {
        IotThreadManager instance = IotThreadManager.instance();
        instance.start(coreProperties);
        return instance;
    }

    /**
     * 自定义调度任务执行器
     * issue：https://gitee.com/iteaj/iot/issues/I5D662
     * @param iotThreadManager
     * @return
     */
    @Bean
    @Lazy
    public ScheduledExecutorService iotScheduledService(IotThreadManager iotThreadManager) {
        return iotThreadManager.getExecutorService();
    }

    /**
     * https://gitee.com/iteaj/iot/issues/I5K0S3
     * @return
     */
    @Bean
    public IotFrameworkReadyListener frameworkReadyListener() {
        return new IotFrameworkReadyListener();
    }

    @Bean
    @ConditionalOnMissingBean
    public ComponentFactory componentFactory() {
        return DefaultComponentFactory.getInstance();
    }

    @Bean
    @ConditionalOnMissingBean
    public ProtocolHandleFactory protocolHandleFactory(@Autowired(required = false) Set<ProtocolHandleProxyMatcher> proxyMatchers) {
        return new ProtocolHandleFactory(proxyMatchers);
    }

    @Bean
    @ConditionalOnMissingBean
    public ProtocolTimeoutManager protocolTimeoutManager(ProtocolHandleFactory handleFactory) {
        return new ProtocolTimeoutManager(handleFactory);
    }
}
